﻿<!DOCTYPE html>
<html>

<head>
	<meta charset=utf-8>
	<title>独自ローダーの設定</title>
	<link href="../base.css" rel="stylesheet" type="text/css" />
</head>

<body>
	<div class="main">
		<h1>独自ローダーの設定</h1>
		
		<h2>概要</h2>
		<p>
Effekseerでは基本的な読込はサポートしていますが、他のゲームエンジンのパッケージから読み込めるようになっていません。
そのため、ローダークラスを追加し、ファイルの読込方法を拡張します。
		</p>

		<h2>エフェクトファイルの読込</h2>
		<p>
エフェクトファイルを読み込むには「::Effekseer::EffectLoader」クラスを継承し、「::Effekseer::Manager::SetEffectLoader」にて設定します。
実際に、通常のファイルシステムから読み込むためのクラスを記述してみます。Load関数でメモリを確保し、Unload関数でメモリを破棄します。
		</p>

<pre>
<code>
class EffectLoader : public ::Effekseer::EffectLoader {
public:
	EffectLoader() {}
	virtual ~EffectLoader() {}
	bool Load( const EFK_CHAR* path, void*& data, int32_t& size );
	void Unload( void* data, int32_t size );
};

bool EffectLoader::Load( const EFK_CHAR* path, void*& data, int32_t& size ) {
	data = NULL;
	size = 0;

	FILE* fp = _wfopen( (const wchar_t*)path, L"rb" );
	if( fp == NULL ) return false;

	fseek( fp, 0, SEEK_END );
	size = (int32_t)ftell( fp );
	data = new uint8_t[size];
	fseek( fp, 0, SEEK_SET );
	fread( data, 1, size, fp );
	fclose( fp );
	
	return true;
}

void EffectLoader::Unload( void* data, int32_t size ) {
	if( data != NULL ) delete [] data;
}

// 設定する。
manager->SetEffectLoader( new EffectLoader() );
</code>
</pre>

		<h2>テクスチャファイルの読込</h2>
		<p>
テクスチャファイルを読み込むには「::Effekseer::TextureLoader」クラスを継承し、「::Effekseer::Manager::SetTextureLoader」にて設定します。
実際に、DirectX9にて通常のファイルシステムから読み込むためのクラスを記述してみます。Load関数でテクスチャを読み込み、Unload関数でテクスチャを破棄します。
		</p>

<pre>
<code>
class TextureLoader : public ::Effekseer::TextureLoader {
private:
	::EffekseerRenderer::Renderer*	m_renderer;

public:
	TextureLoader( ::EffekseerRenderer::Renderer* renderer ) { m_renderer = renderer; }
	virtual ~TextureLoader() {}
	void* Load( const EFK_CHAR* path );
	void Unload( void* data );
};

void* TextureLoader::Load( const EFK_CHAR* path, ::Effekseer::TextureType textureType ) {
	FILE* fp_texture = _wfopen( (const wchar_t *)path, L"rb" );

	if( fp_texture != NULL ) {
		IDirect3DTexture9* texture = NULL;

		fseek( fp_texture, 0, SEEK_END );
		size_t size_texture = ftell( fp_texture );
		char* data_texture = new char[size_texture];
		fseek( fp_texture, 0, SEEK_SET );
		fread( data_texture, 1, size_texture, fp_texture );
		fclose( fp_texture );

		D3DXCreateTextureFromFileInMemory( m_renderer->GetDevice(), data_texture, size_texture, &texture );

		delete [] data_texture;

		return (void*)texture;
	}

	return NULL;
}

void TextureLoader::Unload( void* data ) {
	if( data != NULL ) {
		IDirect3DTexture9* texture = (IDirect3DTexture9*)data;
		texture->Release();
	}
}

// 設定する。
manager->SetTextureLoader( new TextureLoader() );
</code>
</pre>

		<h2>相対パスの問題</h2>
		<p>
テクスチャファイルの場合、渡されるパスはツールで保存した時のテクスチャへの相対パスとなっています。多くの場合、エフェクトファイルを読み込んだ時、エフェクトファイルからの相対パスの位置のテクスチャを読み込む必要があります。その方法として、一例を記述します。TextureLoaderクラスにファイルパスを持たせれるようにし、「::Effekseer::Create::Effect::Create」を実行する前にパスを書き換えます。
		</p>

<pre>
<code>
class TextureLoader : public ::Effekseer::TextureLoader {
private:
	::EffekseerRenderer::Renderer*	m_renderer;

public:
	TextureLoader( ::EffekseerRenderer::Renderer* renderer ) { m_renderer = renderer; }
	virtual ~TextureLoader() {}
	void* Load( const EFK_CHAR* path );
	void Unload( void* data );

	// 読み込み時のルート
	std::wstring RootPath;
};

void* TextureLoader::Load( const EFK_CHAR* path, ::Effekseer::TextureType textureType ) {

	wchar_t dst[260];
	
	// ファイルパスを結合する関数
	Combine( RootPath.c_str(), (const wchar_t *)path, dst, 260 );

	FILE* fp_texture = _wfopen( (const wchar_t *)dst, L"rb" );

	if( fp_texture != NULL ) {
		IDirect3DTexture9* texture = NULL;

		fseek( fp_texture, 0, SEEK_END );
		size_t size_texture = ftell( fp_texture );
		char* data_texture = new char[size_texture];
		fseek( fp_texture, 0, SEEK_SET );
		fread( data_texture, 1, size_texture, fp_texture );
		fclose( fp_texture );

		D3DXCreateTextureFromFileInMemory( m_renderer->GetDevice(), data_texture, size_texture, &texture );

		delete [] data_texture;

		return (void*)texture;
	}

	return NULL;
}

void TextureLoader::Unload( void* data ) {
	if( data != NULL ) {
		IDirect3DTexture9* texture = (IDirect3DTexture9*)data;
		texture->Release();
	}
}

// 設定する。
manager->SetTextureLoader( new TextureLoader() );

// Createを実行する前に指定する。
((TextureLoader*)manager->GetTextureLoader())->RootPath = std::wstring( Path );
::Effekseer::Effect* effect = ::Effekseer::Effect::Create( manager, Path );
</code>
</pre>

	</div>
</body>

</html>